/*
 * Detector.cc
 *
 *  Created on: 14.04.2011
 *      Author: ed
 */

#include "Detector.hh"


#include "G4Material.hh"
#include "G4MaterialTable.hh"
#include "G4Element.hh"
#include "G4LogicalBorderSurface.hh"
#include "G4Box.hh"
#include "G4LogicalVolume.hh"
#include "G4RotationMatrix.hh"
#include "G4ThreeVector.hh"
#include "G4PVPlacement.hh"
#include "G4OpBoundaryProcess.hh"
#include "G4Sphere.hh"
#include "G4GeometryManager.hh"
#include "G4SDManager.hh"
#include "globals.hh"
#include "PrimariesGenerator.hh"
Detector::Detector(G4double R, G4double LAbs, G4double LSc)
{
	r = R;
	lAbs = LAbs;
	lSc = LSc;
	boxSide = r * 1.1;
	trackerSD = new TrackerSD("TrackerSD");
	PhotonEnergy = new G4double[nEntries];
	G4double pe = PrimariesGenerator::GetPhotonEnergy();
	for(int i=0;i<nEntries;i++)
	{
		PhotonEnergy[i] = pe
				+(double)((i-2))*pe/(double)nEntries;

	}
}

Detector::~Detector()
{
	// TODO Auto-generated destructor stub
}
G4VPhysicalVolume* Detector::Construct()
{
	G4Element* N = new G4Element("Nitrogen", "N", 7 , 14.01*g/mole);
	G4Element* O = new G4Element("Oxygen"  , "O", 8 , 16.00*g/mole);

	G4Material* Air = new G4Material("Air", 1.29*mg/cm3, 2);
	Air->AddElement(N, 70.*perCent);
	Air->AddElement(O, 30.*perCent);


	G4Material* Aerogel = new G4Material("Aerogel", 0.1*g/cm3,0);

	G4MaterialPropertiesTable* airMPT = new G4MaterialPropertiesTable();
	G4MaterialPropertiesTable* aerogelMPT = new G4MaterialPropertiesTable();




	//
	// Aerogel
	//
	G4double AerogelRefractiveIndex[nEntries];
	for(int i=0;i<nEntries;i++)
	{
		AerogelRefractiveIndex[i]=1.3;
	}

	G4double AerogelAbsorption[nEntries];
	for(int i=0;i<nEntries;i++)
	{
		AerogelAbsorption[i]=lAbs;
	}

	G4double AirRefractiveIndex[nEntries];
	for(int i=0;i<nEntries;i++)
	{
		AirRefractiveIndex[i]=1.0;
	}
	G4double AerogelReyleighScaterring[nEntries];
	for(int i=0;i<nEntries;i++)
	{
		AerogelReyleighScaterring[i]=lSc;
	}


	aerogelMPT->AddProperty("RAYLEIGH",PhotonEnergy,AerogelReyleighScaterring,nEntries);
	aerogelMPT->AddProperty("ABSLENGTH",PhotonEnergy,AerogelAbsorption,nEntries);
	aerogelMPT->AddProperty("RINDEX",PhotonEnergy,AerogelRefractiveIndex,nEntries);

	airMPT->AddProperty("RINDEX",PhotonEnergy,AirRefractiveIndex,nEntries);

	Aerogel->SetMaterialPropertiesTable(aerogelMPT);
	Air->SetMaterialPropertiesTable(airMPT);

	G4Box* bigAirBox = new G4Box("BigAirBox",boxSide,boxSide,boxSide);
	G4LogicalVolume* bigAirBoxLogical = new G4LogicalVolume(bigAirBox,Air,"AirLogicalBox");


	airBoxPhys = new G4PVPlacement(0,G4ThreeVector(),bigAirBoxLogical,"World",0,false,0);


	G4Sphere* aerogelSphere = new G4Sphere("AerogelSphere",0.0,r,0.0,2*pi,0.0,pi);
	G4LogicalVolume* aerogelSphereLogical = new G4LogicalVolume(aerogelSphere,Aerogel,"AerogelSphere");

	aerogelSpherePhys = new G4PVPlacement(0,G4ThreeVector(),aerogelSphereLogical,"AerogelSpherePhys",
				  bigAirBoxLogical,false,0);
	G4OpticalSurface* aerogelSurface = new G4OpticalSurface("AerogelSurface");
	aerogelSurface->SetType(dielectric_dielectric);
	aerogelSurface->SetFinish(polished);
	aerogelSurface->SetModel(unified);
	//The UNIFIED model assumes that the probability of micro-facet
	//normals populates the annulus of solid angle sin(a)da will be
	//proportional to a gaussian of SigmaAlpha

	aerogelSurface->SetSigmaAlpha(0.1);
	//G4LogicalBorderSurface* WaterSurface =
								 new G4LogicalBorderSurface("AerogelSurface",
								 aerogelSpherePhys,airBoxPhys,aerogelSurface);

	G4SDManager *sdMan = G4SDManager::GetSDMpointer();
	if(sdMan)
	{
	  sdMan->AddNewDetector(trackerSD);
	  aerogelSphereLogical->SetSensitiveDetector(trackerSD);
	}
	return airBoxPhys;
}
void Detector::SetLAbs(G4double LAbs)
{
	if(LAbs==lAbs)
		return;
	G4GeometryManager *geometryManager = G4GeometryManager::GetInstance();
	if(geometryManager==0)
	{
		G4cout<<"Geometry manager is not instantiated yet"<<G4endl;
		return;
	}
	geometryManager->OpenGeometry(aerogelSpherePhys);
	G4MaterialPropertiesTable *t = aerogelSpherePhys->GetLogicalVolume()->GetMaterial()->GetMaterialPropertiesTable();
	G4double pe = PrimariesGenerator::GetPhotonEnergy();
	t->RemoveEntry("ABSLENGTH",pe);
	lAbs = LAbs;
	t->AddEntry("ABSLENGTH",pe,lAbs);
	geometryManager->CloseGeometry(aerogelSpherePhys);
}
void Detector::SetLSc(G4double LSc)
{
	if(LSc==lSc)
		return;
	G4GeometryManager *geometryManager = G4GeometryManager::GetInstance();
	if(geometryManager==0)
	{
		G4cout<<"Geometry manager is not instantiated yet"<<G4endl;
		return;
	}
	geometryManager->OpenGeometry(aerogelSpherePhys);
	G4MaterialPropertiesTable *t = aerogelSpherePhys->GetLogicalVolume()->GetMaterial()->GetMaterialPropertiesTable();
	G4double pe = PrimariesGenerator::GetPhotonEnergy();
	t->RemoveEntry("RAYLEIGH",pe);
	lSc= LSc;
	t->AddEntry("RAYLEIGH",pe,lSc);
	geometryManager->CloseGeometry(aerogelSpherePhys);
}

G4int Detector::GetLightOutput()
{
	return trackerSD->GetLightOutput();
}
G4int Detector::GetParticlesPerEvent()
{
	return trackerSD->GetParticlesPerEvent();
}

